﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using thailandProject.Models;
using thailandProject.ViewModel;
using MvcFilters.Infrastructure.Filters;

namespace thailandProject.Controllers
{
    [ThailandAuthorize(3)]
    public class PropertyController : Controller
    {
        //
        // GET: /Properties/

        public ActionResult Index()
        {
            try
            {
                ViewBag.Header = "Properties";

                if (Session["dateFrom"] == null)
                    Session.Add("dateFrom", "");

                if (Session["dateTo"] == null)
                    Session.Add("dateTo", "");
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View();
        }

        

        [HttpPost]
        public ActionResult Index(DateTime dateFrom, DateTime dateTo)
        {
            List<List<PropertyMatch>> properties = new List<List<PropertyMatch>>();
            try
            {
                ViewBag.Header = "Properties";

                Session["dateFrom"] = dateFrom.ToShortDateString();
                Session["dateTo"] = dateTo.ToShortDateString();
                properties = Models.PropertyMatch.getPropertyMatches(dateFrom, dateTo);
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(properties);
        }

        [HttpPost]
        [ThailandAuthorize]
        public ActionResult SelectClient(string btnSubmit, FormCollection data)
        {
            try
            {
                ViewBag.Header = "Select Client";

                List<PropertyMatch> properties = new List<PropertyMatch>();
                List<PropertyMatch> finalList = new List<PropertyMatch>();

                //If a property was selected
                if (data["cbProperty"] != null)
                {
                    string[] checkedProperties = data["cbProperty"].Split(',');
                    List<string> props = new List<string>();
                    for (int i = 0; i < checkedProperties.Length; i++)
                    {
                        if (checkedProperties[i].Contains("_use"))
                            props.Add(checkedProperties[i].Replace("_use", ""));
                    }

                    string[] cbProperties = props.ToArray<string>();

                    //All checkboxes's values are stored as a comma-separated list
                    int[] propertyIds = new int[cbProperties.Length];

                    //Convert all strings into a numeric id
                    for (int i = 0; i < cbProperties.Length; i++)
                    {
                        if (cbProperties[i].IndexOf('_') == -1)
                            propertyIds[i] = Convert.ToInt32(cbProperties[i].Substring(0, cbProperties[i].Length - 1)); //Length-1 is 'c'
                        else
                            propertyIds[i] = Convert.ToInt32(cbProperties[i].Substring(0, cbProperties[i].IndexOf('_') - 1)); //Length-1 is 'p_x'

                    }

                    properties = PropertyMatch.getPropertiesFromIds(propertyIds);

                    //for each returned property
                    foreach (PropertyMatch pm in properties)
                    {
                        //Match to it's corresponding ID
                        for (int i = 0; i < propertyIds.Length; i++)
                        {
                            if (propertyIds[i] == pm.property.propID)
                            {

                                //If it was a complete match
                                if (cbProperties[i].Substring(cbProperties[i].Length - 1, 1) == "c")
                                {
                                    //Set the start and end date to be the values saved in Session
                                    pm.startDate = Convert.ToDateTime(Session["dateFrom"].ToString());
                                    pm.endDate = Convert.ToDateTime(Session["dateTo"].ToString());
                                    pm.quotedPrice = Convert.ToDecimal(data["quotedPrice" + pm.property.propID]);
                                    pm.isPartial = false;
                                    pm.isOnHold = data[cbProperties[i] + "Hold"] != null ? true : false;
                                    finalList.Add(pm);
                                }
                                else //It was a partial match
                                {
                                    //get the dateFrom and dateTo from the "pDateFrom(propId)" and "pDateTo(propId)" fields
                                    int repeatCount = 0;
                                    int firstOccurance = -1;
                                    for (int j = 0; j < cbProperties.Length; j++)
                                    {
                                        if (cbProperties[i].Contains(propertyIds[j] + "p_"))
                                        {
                                            repeatCount++;
                                            if (firstOccurance == -1)
                                                firstOccurance = j;
                                        }
                                    }

                                    for (int j = 0; j < repeatCount; j++)
                                    {
                                        string repeatIndex = cbProperties[firstOccurance + j].
                                            Substring(cbProperties[firstOccurance + j].IndexOf('_'),
                                            cbProperties[firstOccurance + j].Length - cbProperties[firstOccurance + j].IndexOf('_'));

                                        //because the same property may have been selected for two different timeframes, use split
                                        string fromDate = (data["pDateFrom" + propertyIds[i] + repeatIndex].ToString());
                                        string toDate = (data["pDateTo" + propertyIds[i] + repeatIndex].ToString());
                                        string quotedPrice = (data["quotedPrice" + propertyIds[i] + repeatIndex]);

                                        //These string arrays will all be the same size

                                        PropertyMatch pMatch = new PropertyMatch();
                                        pMatch.property = pm.property;
                                        pMatch.startDate = Convert.ToDateTime(fromDate);
                                        pMatch.endDate = Convert.ToDateTime(toDate);
                                        pMatch.quotedPrice = Convert.ToDecimal(quotedPrice);
                                        pMatch.isPartial = true;
                                        pMatch.isOnHold = data[cbProperties[i] + "Hold"] != null ? true : false;

                                        finalList.Add(pMatch);
                                    }
                                }

                                break;
                            }
                        }//End to for propertyIds
                    }//End to foreach PropertyMatch

                    //Save this for later postbacks so it is not forgotten
                    //This will be stored as an application variable so it lasts until the server is terminated, or
                    //the program decides it is "consumed"
                    USER user = (USER)Session["user"];
                    if (HttpContext.Application["properties" + user.userID] == null)
                        HttpContext.Application.Add("properties" + user.userID, finalList);
                    else
                        HttpContext.Application["properties" + user.userID] = finalList;
                    
                    /*if (Session["properties"] == null)
                        Session.Add("properties", finalList);
                    else
                        Session["properties"] = finalList;*/
                }

                //Differentiate which submit button was pressed. If it was to email a potential client, pass this
                //information to the Email section.
                //Otherwise, show the ability to select a client to make the reservation
                if (btnSubmit == "email")
                {
                    ThailandEntities a = new ThailandEntities();

                    int userID = 1; // ((USER)Session["user"]).userID;
                    EMAILPREFERENCE pref = null;
                    var prefs = from p in a.EMAILPREFERENCEs
                                where p.userID == userID
                                select p;
                    if (prefs.Count() > 0)
                        pref = prefs.ToList()[0];
                    
                    string message = "";
                    if(pref != null && !String.IsNullOrEmpty(pref.onPropInquiryTemplate))
                        message = EmailGenerator.generateOnPropInquiry(new EmailTemplateModel("onPropInquiry", pref.onPropInquiryTemplate), "<<Insert Name>>", finalList);
                    else
                        message = EmailGenerator.generateEmailText(finalList, "<<Insert Name>>");

                    if (Session["emailMessage"] == null)
                        Session.Add("emailMessage", message);
                    else
                        Session["emailMessage"] = message;

                    return RedirectToAction("Compose", "Email");
                }
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return RedirectToAction("Compose", "Email");
        }

        [HttpPost]
        public ActionResult SelectClient2(string clientName)
        {
            try
            {
                ViewBag.Header = "Select Client";

                if (Session["searchName"] == null)
                    Session.Add("searchName", clientName);
                else
                    Session["searchName"] = clientName;

                // This is the real return statement
                return SelectClient2(1, "clientFirstName");
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
        }

        [HttpGet]
        public ActionResult SelectClient2(int? pageNumber, string sortType)
        {
            PagedList<CLIENT> clients = new PagedList<CLIENT>();

            try
            {
                ViewBag.PageNumber = pageNumber == 0 ? (int)Session["pageNumber"] : pageNumber;
                if (Session["pageNumber"] == null)
                    Session.Add("pageNumber", 1);
                else
                    Session["pageNumber"] = pageNumber;

                //If the sort type changes, then update it
                if (!String.IsNullOrEmpty(sortType))
                    ViewBag.SortType = sortType;
                else
                    sortType = ViewBag.SortType;

                string clientName = (string)Session["searchName"];

                clients = ClientSort.getSortedClientList(clientName, sortType, 10, pageNumber.Value);
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View("SelectClient", clients);
        }

        [HttpGet]
        public ActionResult SelectClientReserve(int clientId)
        {
            try
            {
                List<RESERVATION> newRes = new List<RESERVATION>();

                //For each apartment intended to be reserved, create a RESERVATION object
                List<PropertyMatch> properties = (List<PropertyMatch>)Session["properties"];
                foreach (PropertyMatch prop in properties)
                {
                    RESERVATION r = new RESERVATION();
                    r.resStartDate = prop.startDate;
                    r.resEndDate = prop.endDate;
                    r.resQuotedPrice = prop.quotedPrice;
                    r.propID = prop.property.propID;
                    r.clientID = clientId;
                    r.resIsHeld = true;
                    r.resDate = DateTime.Now;
                    r.resIsHeld = true; //By default, every reservation is on hold
                    r.userID = 1; //Until I can get which user is reserving this, I hope Richard is always id 1

                    newRes.Add(r);
                }

                //Reserve the property
                using (ThailandEntities a = new ThailandEntities())
                {
                    foreach (RESERVATION r in newRes)
                    {
                        a.RESERVATIONs.AddObject(r);
                    }
                    a.SaveChanges(); //Commit all the added objects to the database
                }
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            //Redirect to the client's page to show the new reservations
            return RedirectToAction("ViewClient", "Clients", new { clientId = clientId });
        }

        public ActionResult ViewAllProperties()
        {
            try
            {
                Models.ThailandEntities a = new Models.ThailandEntities();

                var all = from allclients in a.PROPERTies
                      select allclients;
                return View(all);
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
        }

        [HttpGet]
        public ActionResult ViewProperty(int propId)
        {
            PROPERTY prop = new PROPERTY();
            try
            {
                ViewBag.Header = "Property Details";

                ThailandEntities a = new ThailandEntities();

                var properties = from property in a.PROPERTies
                                 where property.propID == propId
                                 select property;
                prop = properties.ToList()[0];
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(prop);
        }
    }
}
